package com.sky.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.entity.SetmealDish;
import com.sky.constant.MessageConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishFlavourMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.pojo.Category;
import com.sky.pojo.Dish;
import com.sky.service.DishService;
import com.sky.mapper.DishMapper;
import com.sky.vo.DishVO;
import com.sky.vo.pageResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Morpeko
 * @description 针对表【dish(果蔬)】的数据库操作Service实现
 * @createDate 2024-08-06 13:20:29
 */
@Service
@Slf4j
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavourMapper dishFlavourMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;

    /**
     * **Path：** /admin/dish/page
     * <p>
     * **Method：** GET<br>
     * <p>
     * **接口描述：**<br>
     * <p>
     * <p>
     * ### 请求参数
     * <p>
     * **Query**<br>
     * <b>果蔬条件分页查询</b>
     */
    @Override
    public pageResultVO<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO) {
        //设置分页查询参数,设置排序字段和规则
        PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize(), "create_time desc");
        //设置用于条件查询的dish实体类对象
        Dish dish = new Dish().builder()
                .name(dishPageQueryDTO.getName())
                .categoryId(dishPageQueryDTO.getCategoryId())
                .status(dishPageQueryDTO.getStatus())
                .build();
        //业务实现:条件分页查询果蔬数据
        Page<DishVO> dishPage = dishMapper.pageQuery(dish);
        //封装分页查询结果VO
        pageResultVO<DishVO> pageResultVO = new pageResultVO<>();
        pageResultVO.setTotal(dishPage.getTotal());//总记录数
        pageResultVO.setRecords(dishPage.getResult());//条件分页查询结果
        //响应分页查询结果VO
        return pageResultVO;
    }

    /**
     * 修改果蔬信息
     *
     * @param dishDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)//默认回滚运行时异常，如果方法抛出异常，事务会回滚
    public void updateDish(DishDTO dishDTO) {
        //1.创建用于修改果蔬信息的dish实体类对象
        Dish updateDish = new Dish().builder()
                .id(dishDTO.getId())
                .name(dishDTO.getName())
                .image(dishDTO.getImage())
                .description(dishDTO.getDescription())
                .categoryId(dishDTO.getCategoryId())
                .price(dishDTO.getPrice())
                .status(dishDTO.getStatus())
                .build();
        //2.获取果蔬口味列表
        List<DishFlavor> flavors = dishDTO.getFlavors();
        //3.业务实现:根据果蔬id修改果蔬信息
        dishMapper.updateDish(updateDish);
        //4.如果前端传过来的果蔬口味列表不为空,则先删除原有果蔬口味信息,再批量新增果蔬口味信息
        //删除原有果蔬口味信息
        dishFlavourMapper.deleteDishFlavourByDishId(dishDTO.getId());
        if (flavors != null && flavors.size() > 0) {
            //补充设置flavors中的dishId属性
            flavors.forEach(flavor -> {
                flavor.setDishId(dishDTO.getId());
            });
            //批量插入新的果蔬口味信息列表
            dishFlavourMapper.insertDishFlavour(flavors);
        }


    }

    /**
     * @Description: 新增果蔬
     * @Param: [dishDTO]
     * @return: void
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    //事务的两个属性：rollbackFor和 propagation，默认情况下，事务的传播行为是REQUIRED，如果方法抛出异常，事务会回滚。
    public void saveDish(DishDTO dishDTO) {

        //业务实现:新增果蔬信息
        //创建用来新增果蔬信息的dish实体类对象
//        Dish dish = new Dish().builder()
//                .id(dishDTO.getId())
//                .name(dishDTO.getName())
//                .image(dishDTO.getImage())
//                .description(dishDTO.getDescription())
//                .categoryId(dishDTO.getCategoryId())
//                .price(dishDTO.getPrice())
//                .status(dishDTO.getStatus())
//                .build();
        //拷贝dishDTO到dish实体类对象
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        //新增一条果蔬信息
        dishMapper.insert(dish);
        //获取insert语句通过useGeneratedKeys=true keyProperty="id"获得的返回实体类对象id的插入记录的主键值
        Long dishId = dish.getId();
        //获取果蔬口味列表,并且设置果蔬id
        List<DishFlavor> flavors = dishDTO.getFlavors();
        log.info("果蔬口味列表：{}", flavors);
        if (flavors != null && flavors.size() > 0) {//如果果蔬口味列表不为空
            flavors.forEach(flavor -> {
                flavor.setDishId(dishId);//设置果蔬id
            });
            //只有当果蔬口味列表不为空时才新增果蔬口味信息
            //批量新增果蔬口味信息
            dishFlavourMapper.insertDishFlavour(flavors);
        }
    }

    @Override
    //进行多表的操作，需要事务注解
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void deleteDish(List<Long> ids) {
        //1. todo 判断果蔬是否为起售状态-->起售状态的果蔬不能删除
        //根据ids查询起售状态的果蔬
        Dish dish = dishMapper.selectOnStatusbyIds(ids);//查询起售状态的果蔬

        if (dish != null) {
            throw new RuntimeException(MessageConstant.DISH_ON_SALE);//抛出起售状态的果蔬不能删除的异常
        }
        //判断果蔬是否有套餐关联-->有套餐关联的果蔬不能删除
        SetmealDish setmealDish = setmealDishMapper.selectByDishIds(ids);//查询果蔬是否有套餐关联
        if (setmealDish != null) {
            throw new RuntimeException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);//抛出有套餐关联的果蔬不能删除的异常
        }
        //业务实现:删除/批量删除果蔬信息
        if (ids != null && ids.size() > 0) {
            dishMapper.deleteDish(ids);
        }
        //删除果蔬关联的果蔬口味信息
        dishFlavourMapper.deleteDishFlavourByDishIds(ids);
    }

    @Override
    public DishVO getDishById(Long id) {
        //业务实现:根据id多表查询果蔬信息,查询果蔬表关联查询分类表得到分类名称
        DishVO dishVO = dishMapper.selectDishById(id);

        //根据查询到的dishVO的id,查询dish_flavour表获取果蔬口味信息
        List<DishFlavor> dishFlavor = dishFlavourMapper.selectDishFlavourByDishId(id);

        //封装查询到的dishVO对象
        dishVO.setFlavors(dishFlavor);
        return dishVO;
    }

    /**
     * 根据分类id查询果蔬列表
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<Dish> listDishByCategoryId(Long categoryId) {

        //业务实现:根据categoryId查询果蔬列表
        List<Dish> dishList = dishMapper.selectDishByCategoryId(categoryId);
        return dishList;
    }

    /**
     * 根据果蔬ID修改果蔬状态-->启用/禁用果蔬
     *
     * @param status
     * @param id
     */
    @Override
    public void updateStatus(Integer status, Long id) {
        if (status == null || id == null) {
            throw new RuntimeException(MessageConstant.DISH_NOT_EXIST);
        }
        //业务实现:根据id修改果蔬状态,启用/禁用果蔬
        dishMapper.updateStatus(status, id);

    }
    /**
     * 条件查询果蔬和口味
     * @param dish
     * @return
     */
    /**
     * 1.查询获取List<Dish><br>
     * 2.准备封装List<Dish>的List<DishVO><br>
     * 2.遍历List<Dish>，封装到List<DishVO><br>
     * 3,创建DishVO对象，把Dish对象属性复制到DishVO对象中<br>
     * 4.根据Dish对象id查询List<DishFlavor>,设置到DishVO对象中<br>
     * 5.添加到DishVO对象到List<DishVO>中<br>
     * 6.返回List<DishVO><br>
     */


    @Override
    public List<DishVO> listWithFlavor(Dish dish) {
        //1.查询果蔬列表
        List<Dish> dishList = dishMapper.list(dish);
//        List<DishVO> resultList = dishVOS.getResult();//从分页查询结果中获取果蔬列表
//        //没有设置分页查询条件，默认查询第一页，每页10条数据
        //2.封装List<Dish>到List<DishVO>
        List<DishVO> dishVOList = new ArrayList<>();//创建DishVO列表
        for (Dish dish1 : dishList) {//遍历List<Dish>
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(dish1, dishVO);
            //根据果蔬id查询对应的口味
            List<DishFlavor> flavors = dishFlavourMapper.selectDishFlavourByDishId(dish1.getId());
            dishVO.setFlavors(flavors);//设置口味信息到DishVO对象中
            dishVOList.add(dishVO);//添加到DishVO列表中
        }
        //3.返回查询结果
        return dishVOList;
    }

}




